package gl.java.network.transport.kcp.udp;

import io.netty.bootstrap.UdpServerBootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.DatagramPacket;
import io.netty.handler.logging.LogLevel;
import io.netty.handler.logging.LoggingHandler;
import io.netty.util.concurrent.Future;
import io.netty.util.concurrent.GenericFutureListener;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class UmspUdpServer {
    public static void main(String[] args) {
        try {
            UdpServerBootstrap b = new UdpServerBootstrap();
            EventLoopGroup group = new NioEventLoopGroup();
            b.group(group).channel(UdpServerChannel.class)
//                    .option(ChannelOption.SO_BROADCAST, true)
                    .childHandler(new ChannelInitializer<UdpServerChildChannel>() {
                        @Override
                        protected void initChannel(UdpServerChildChannel ch) throws Exception {
                            ch.pipeline().addLast(
//                                    new LoggingHandler(LogLevel.INFO),
                                    new UdpServerHandler());
                        }

                    });

            b.bind(2555).sync().channel().closeFuture().await();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }

    private static class UdpServerHandler extends SimpleChannelInboundHandler<DatagramPacket> {

        public void channelActive(ChannelHandlerContext ctx) throws Exception {
            log.info("UdpServerHandler.active ctx.id:" +
                    "" + ctx.channel().id());
            ctx.fireChannelActive();
        }

        public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
            log.info("UdpServerHandler.channel Read:ref cnt        "+((DatagramPacket)msg).refCnt());
            super.channelRead(ctx,msg);
        }
        int i = 0;
        @Override
        protected void channelRead0(ChannelHandlerContext ctx, DatagramPacket packet) throws Exception {
            ByteBuf buf = packet.copy().content();

            log.info("[recv]UdpServerHandler.channelRead0:ref cnt    "+packet.refCnt());
            byte[] req = new byte[buf.readableBytes()];
            buf.readBytes(req);
            log.info("[recv]UdpServerHandler.channelRead0:"+req[0]);

            //向客户端发送消息
            final ByteBuf heapBuffer = Unpooled.buffer(16);
            heapBuffer.writeByte((byte)0x8);
            heapBuffer.writeByte((byte)i++);
            DatagramPacket data = new DatagramPacket(heapBuffer, packet.sender());
            ctx.writeAndFlush(data).addListeners(new GenericFutureListener<Future<? super Void>>() {
                @Override
                public void operationComplete(Future<? super Void> future) throws Exception {
//                    heapBuffer.release();
                }
            });

        }
    }
}
